package logic

import (
	"context"
	"strings"

	"mall/common/enumx"
	"mall/common/modelx"
	"mall/common/resultx"
	"mall/service/forum/model"
	"mall/service/forum/rpc/internal/svc"
	"mall/service/forum/rpc/types/forum"

	"github.com/zeromicro/go-zero/core/logx"
)

type CollectListLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewCollectListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CollectListLogic {
	return &CollectListLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *CollectListLogic) CollectList(in *forum.CollectListReq) (*forum.CollectListResp, error) {
	logx.Infof("CollectListReq: %+v ", in)
	// CollectListReq: 

	if in.Preload == "" && in.EagerLoad == "" {
		return nil, resultx.StatusError(resultx.REUQEST_PARAM_ERROR, "")
	}

	if in.Filter == "" {
		return nil, resultx.StatusError(resultx.REUQEST_PARAM_ERROR, "")
	}

	preloadMap, eagerLoadMap := modelx.GetPreloadMap(in.Preload, in.EagerLoad)
	logx.Infof("preloadMap: %+v ", preloadMap)
	// preloadMap: 
	logx.Infof("eagerLoadMap: %+v ", eagerLoadMap)
	// eagerLoadMap: 

	forumCollectEntityName := model.RpcEntityNames.ForumCollect
	_, hasSettingMap := model.RpcEntityPreloadMap[forumCollectEntityName] // ForumCollect的关联字段
	if !hasSettingMap {
		return &forum.CollectListResp{}, nil
	}

	forumCollectRepositoryName := model.RepositoryNames.ForumCollect
	columnMap, hasColumnMap := model.RepositoryPreloadMap[forumCollectRepositoryName] // ForumCollect的数据库字段
	if !hasColumnMap {
		return &forum.CollectListResp{}, nil
	}

	var selectCols []string
	if preloadFields, hasPreloadFields := preloadMap[forumCollectEntityName]; hasPreloadFields {
		selectColMap := make(map[string]string)
		for _, field := range preloadFields {
			if _, exist := selectColMap[field]; !exist {
				if column, hasColumn := columnMap[field]; hasColumn {
					selectColMap[field] = column
				} else {
					selectColMap[field] = ""
				}
			}
		}
		for _, column := range selectColMap {
			if column != "" {
				selectCols = append(selectCols, column)
			}
		}
	}

	filterMap := modelx.GetFilterMap(in.Filter, columnMap)
	filterMap[model.ForumUserCollectColumns.PlatformID] = map[string][]interface{}{
		"equalTo": []interface{}{in.PlatformId},
	}
	filterMap[model.ForumUserCollectColumns.Status] = map[string][]interface{}{
		"equalTo": []interface{}{enumx.ObjectStatusAproved},
	}
	logx.Infof("filterMap: %+v ", filterMap)
	// filterMap: 

	var count int64
	var total int64
	var err error
	var collectList []*model.ForumUserCollect

	var orderBy string
	switch in.Sorter {
	case "1":
		orderBy = model.ForumUserCollectColumns.SorterValue3 // minProductGems
	case "2":
		orderBy = model.ForumUserCollectColumns.SorterValue3 + " DESC"
	case "3":
		orderBy = model.ForumUserCollectColumns.SorterValue1 // Slug
	case "4":
		orderBy = model.ForumUserCollectColumns.SorterValue4 + " DESC" // averageRating
	case "5":
		orderBy = model.ForumUserCollectColumns.SorterValue5 + " DESC" // popularity
	case "6":
		orderBy = model.ForumUserCollectColumns.SorterValue2 // year
	case "7":
		orderBy = model.ForumUserCollectColumns.SorterValue2 + " DESC" // year
	default:
		orderBy = model.ForumUserCollectColumns.CollectID + " DESC"
	}
	collectList, count, err = l.svcCtx.ForumUser.GetCollects(l.ctx, model.M{
		"offset":  in.Offset,
		"limit":   in.Limit,
		"orderBy": orderBy,
		"select":  strings.Join(selectCols, ","),
	}, 2, filterMap)
	if err != nil {
		return nil, err
	}

	var collects []*forum.CollectInfo
	if len(collectList) > 0 {
		if eagerLoadEntities, hasEagerLoadEntities := eagerLoadMap[forumCollectEntityName]; hasEagerLoadEntities {
			for _, entity := range eagerLoadEntities {
				if entity == "total" {
					_, total, err = l.svcCtx.ForumUser.GetCollects(l.ctx, model.M{}, 0, filterMap)
					if err != nil {
						total = 0
					}
					break
				}
			}
		}

		for _, collect := range collectList {
			var meta []*forum.ForumMeta
			if collect.SorterValue1.Valid && collect.SorterValue1.String != "" {
				meta = append(meta, &forum.ForumMeta{
					Key:   "slug",
					Value: collect.SorterValue1.String,
				})
			}
			if collect.SorterValue2.Valid && collect.SorterValue2.String != "" {
				meta = append(meta, &forum.ForumMeta{
					Key:   "year",
					Value: collect.SorterValue2.String,
				})
			}
			if collect.SorterValue3.Valid && collect.SorterValue3.String != "" {
				meta = append(meta, &forum.ForumMeta{
					Key:   "minProductGems",
					Value: collect.SorterValue3.String,
				})
			}
			if collect.SorterValue4.Valid && collect.SorterValue4.String != "" {
				meta = append(meta, &forum.ForumMeta{
					Key:   "averageRating",
					Value: collect.SorterValue4.String,
				})
			}
			if collect.SorterValue5.Valid && collect.SorterValue5.String != "" {
				meta = append(meta, &forum.ForumMeta{
					Key:   "popularity",
					Value: collect.SorterValue5.String,
				})
			}
			if collect.FilterValue3.Valid && collect.FilterValue3.String != "" {
				meta = append(meta, &forum.ForumMeta{
					Key:   "season",
					Value: collect.FilterValue3.String,
				})
			}

			collects = append(collects, &forum.CollectInfo{
				Id:         int64(collect.CollectID),
				UserId:     int64(collect.UserID),
				PlatformId: int32(collect.PlatformID),
				ObjectId:   int64(collect.ObjectID),
				ObjectType: int32(collect.ObjectType),
				Status:     int32(collect.Status),
				CreatedAt:  modelx.FormatTime(collect.CreatedAt, ""),
				UpdatedAt:  modelx.FormatTime(collect.UpdatedAt, ""),
				Meta:       meta,
			})
		}
	}

	var hasNextPage int32
	var hasPreviousPage int32
	if count > 1 {
		hasNextPage = 1
		count -= 2
	}
	if count > 0 {
		hasPreviousPage = 1
	}
	return &forum.CollectListResp{
		Data:            collects,
		HasNextPage:     hasNextPage,
		HasPreviousPage: hasPreviousPage,
		Total:           total,
	}, nil
}
